﻿using HelixToolkit.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using Zhaoxi.DigitalTwin.Base;

namespace QuickStart_Project_01.Model3Ds
{
    public class KerbModel3D : UIElement3D
    {
        public Point3DCollection Positions
        {
            get { return (Point3DCollection)GetValue(PositionsProperty); }
            set { SetValue(PositionsProperty, value); }
        }
        public static readonly DependencyProperty PositionsProperty =
            DependencyProperty.Register("Positions",
                typeof(Point3DCollection),
                typeof(KerbModel3D),
                new PropertyMetadata(new Point3DCollection(),
                    new PropertyChangedCallback((s, e) => (s as KerbModel3D).InitModel())));

        public Brush KerbTexture
        {
            get { return (Brush)GetValue(KerbTextureProperty); }
            set { SetValue(KerbTextureProperty, value); }
        }
        public static readonly DependencyProperty KerbTextureProperty =
            DependencyProperty.Register("KerbTexture", typeof(Brush), typeof(KerbModel3D),
                new PropertyMetadata(null,
                    new PropertyChangedCallback((s, e) => (s as KerbModel3D).SetTexture())));

        public double Width { get; set; } = 0.7;
        public double Height { get; set; } = 0.5;

        GeometryModel3D kerbModel = new GeometryModel3D();

        public KerbModel3D()
        {
            this.InitModel();
            this.Visual3DModel = this.kerbModel;
        }
        public void SetTexture()
        {
            this.kerbModel.Material =
                this.kerbModel.BackMaterial =
                this.KerbTexture != null ?
                new DiffuseMaterial(this.KerbTexture) { AmbientColor = Colors.White } : null;
        }
        private void InitModel()
        {
            var builder = new MeshBuilder(false, true);

            // 管道的截面形状（点的集合）
            var section = new PointCollection();
            int m = 40;
            double n = 3;
            double x = this.Width / 2;
            double y = this.Height;

            for (int i = 0; i < m; i++)
            {
                double t = Math.PI * i / (m - 1);
                section.Add(new Point(
                    x * Math.Sign(Math.Cos(t)) * Math.Pow(Math.Abs(Math.Cos(t)), 2 / n),
                    -y * Math.Sign(Math.Sin(t)) * Math.Pow(Math.Abs(Math.Sin(t)), 2 / n)
                    ));
            }

            // 贴图的纹理处理
            var textures = new List<double>() { 0 };
            for (int i = 1; i < this.Positions.Count; i++)
            {
                var d = this.Positions[i - 1].DistanceTo(this.Positions[i]);
                textures.Add(textures[textures.Count - 1] + d);
            }

            builder.AddTube(Positions, null, textures, null, section, new Vector3D(1, 0, 0), false, false);
            this.kerbModel.Geometry = builder.ToMesh();
        }
    }
}
